
#ifndef _C_EVENT_H_
#define _C_EVENT_H_

#include <cTools/Common.h>
#include <cTools/Thread.h>
#include <cTools/Queue.h>

struct _C_Event;

typedef void (*C_Event_Cleanup_t)(struct _C_Event*);

typedef int (*C_Event_Handler_t)(struct _C_Event*);

typedef struct _C_Event
{
	/** Pointer to a user-defined 'd-tor' function **/
	C_Event_Cleanup_t	Cleanup;
	/** Pointer to a handler function **/
	C_Event_Handler_t	Handler;
	/** User defined data **/
	void*				User;
	/** User defined identifier **/
	unsigned int		UserId;
} C_Event;

typedef C_Event* C_Event_Ptr;

/**
 * Create C_Event object.
 */
C_Event_Ptr
C_Event_New(C_Event_Handler_t);

/**
 * Initialize C_Event structure.
 */
void
C_Event_Init(C_Event_Ptr, C_Event_Handler_t);

/**
 * Cleanup function for C_Event base class.
 */
void
C_Event_Base_Cleanup(C_Event_Ptr);

/**
 * Cleanup function. It first calls user provided cleanup function.
 */
void
C_Event_Cleanup(C_Event_Ptr);

/**
 * Destroy C_Event object. First it calls user-defined cleanup function.
 * Then it releases memory.
 */
void
C_Event_Free(C_Event_Ptr);

void
C_Event_Set_Cleanup(C_Event_Ptr, C_Event_Cleanup_t);

/**
 * Set user defined pointer.
 */
C_Bool_t
C_Event_Set_User(C_Event_Ptr, void*, unsigned int);

/**
 * Set event handler callback.
 */
C_Bool_t
C_Event_Set_Handler(C_Event_Ptr, C_Event_Handler_t);

#define C_EVENT_CLEANUP(e) \
	C_Event_Cleanup((C_Event_Ptr)e)

#define C_EVENT_FREE(e) \
	C_Event_Free((C_Event_Ptr)e)

#define C_EVENT_SET_CLEANUP(e, f) \
	C_Event_Set_Cleanup((C_Event_Ptr)e, (C_Event_Cleanup_t) f)

#define C_EVENT_SET_USER(e, ptr, id) \
	C_Event_Set_User((C_Event_Ptr)e, ptr, id)

#define C_EVENT_SET_HANDLER(e, f) \
	C_Event_Set_Handler((C_Event_Ptr)e, (C_Event_Handler_t)f)

/******************************************************************************/

#define EVENT_THREAD_WAIT_MS 500

typedef struct _C_Event_Thread
{
	C_Thread		Thread;
	C_Queue_Ptr		Queue;
	C_Bool_t		QueueOwner;
} C_Event_Thread;

typedef C_Event_Thread* C_Event_Thread_Ptr;

C_Event_Thread_Ptr
C_Event_Thread_New(C_Queue_Ptr);

/**
 * Event thread initialization function.
 */
void
C_Event_Thread_Init(C_Event_Thread_Ptr, C_Queue_Ptr);

void
C_Event_Thread_Run(C_Thread_Ptr);

void
C_Event_Thread_Cleanup(C_Event_Thread_Ptr);

/******************************************************************************/

C_Queue_Ptr
C_Event_Queue_Get_Instance(void);

void
C_Event_Queue_Free_Instance(void);

#endif
